
// Written by Mochan Shrestha

#include "stdafx.h"

/* Serpenski polyhedra engine development under GLUT */
#include <windows.h>
#include <GL/gl.h>

#include "schlicker.h"

#include "tetrahedron.h"
#include "octahedron.h"
#include "cube.h"
#include "icosahedron.h"
#include "dodecahedron.h"

Polyhedra* p = NULL;
float angle = 0.0f;
int cur_i = 1;
int cur_pol = 1;
float cur_r = 3.5f;
int coloring_mode = 0;
int colortheme = 0;

void MakePolyhedra()
{
	if (p != NULL)
		delete p;

	switch (cur_pol)
	{
	case 1:
		p = new Tetrahedron (1.0f, cur_i, cur_r);
		break;
	case 2:
		p = new Octahedron (1.0f, cur_i, cur_r);
		break;
	case 3:
		p = new Cube (1.0f, cur_i, cur_r);
		break;
	case 4:
		p = new Icosahedron (1.0f, cur_i, cur_r);
		break;
	case 5:
		p = new Dodecahedron (1.0f, cur_i, cur_r);
		break;
	}

	p -> SetModes (coloring_mode, colortheme);
	p -> SetColor (1.0, 0.0, 0.0);
	p -> SetIterative ( true );
	p -> Make();
}

void MainMenu (int value)
{
	cur_pol= value;
	MakePolyhedra();
}

void RMenu (int value)
{
	if (value == 4)
	{
		cur_r = SchlickerKunnen (cur_pol - 1);
		MakePolyhedra();
		return;
	}
	cur_r = (value - 1) / 2.0f + 2.0f;
	MakePolyhedra();
}

void IMenu (int value)
{
	cur_i = value;
	MakePolyhedra();
}

void CMMenu (int value)
{
	coloring_mode = value;
	MakePolyhedra();
}

void GCMenu (int value)
{
	coloring_mode = 0;
	colortheme = value;
	MakePolyhedra();
}

void InitMenu()
{
	int mainmenu, rmenu, imenu, coloring_mode;
	int gourand_colors;

	gourand_colors = glutCreateMenu (GCMenu);
	glutAddMenuEntry ("HSV Across", 0);
	glutAddMenuEntry ("HSV Updown", 1);
	glutAddMenuEntry ("Purple Red", 2);
	glutAddMenuEntry ("Red and Blue", 3);
	glutAddMenuEntry ("RGB", 4);
	coloring_mode = glutCreateMenu (CMMenu);
	glutAddSubMenu ("Gourand Colors", gourand_colors);
	glutAddMenuEntry ("Single Color", 1);

	rmenu = glutCreateMenu (RMenu);
	glutAddMenuEntry ("2.0", 1);
	glutAddMenuEntry ("2.5", 2);
	glutAddMenuEntry ("3.0", 3);
	glutAddMenuEntry ("Use Schlicker Kunnen Ratio", 4);

	imenu = glutCreateMenu (IMenu);
	glutAddMenuEntry ("0", 0);
	glutAddMenuEntry ("1", 1);
	glutAddMenuEntry ("2", 2);
	glutAddMenuEntry ("3", 3);
	glutAddMenuEntry ("4", 4);
	glutAddMenuEntry ("5", 5);

	mainmenu = glutCreateMenu (MainMenu);
	glutAddSubMenu ("Coloring Mode", coloring_mode);
	glutAddSubMenu ("R", rmenu);
	glutAddSubMenu ("I", imenu);
	glutAddMenuEntry ("Tetrahedron", 1);
	glutAddMenuEntry ("Octahedron", 2);
	glutAddMenuEntry ("Cube", 3);
	glutAddMenuEntry ("Icosahedron", 4);
	glutAddMenuEntry ("Dodecahedron", 5);
	glutAttachMenu (GLUT_RIGHT_BUTTON);
}


void init (void)
{
	float light_position[] = {0.0, 0.0, -10.0, 1.0};

	glClearColor (0.0, 0.0, 0.0, 1.0);

	glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);

	glLightfv (GL_LIGHT0, GL_POSITION, light_position);

	glEnable (GL_DEPTH_TEST);
	glEnable (GL_COLOR_MATERIAL);
	glShadeModel (GL_SMOOTH);

	glEnable (GL_LIGHTING);
	glEnable (GL_LIGHT0);

	InitMenu();

	MakePolyhedra();
}

void display (void)
{
	glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glPushMatrix();
		glRotatef (angle, 0.0f, 0.7f, 0.0f);
		glColor3f (0.0, 0.0, 1.0);
		p -> Draw();
	glPopMatrix();

	glutSwapBuffers();
}

void idle (void)
{
	angle += 0.01f;
	if ( angle > 360.0f )
		angle = 0.0f;
	glutPostRedisplay();
}

void reshape (int w, int h)
{
	glViewport (0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity();
	gluPerspective (40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0);
	glMatrixMode (GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt (0.0, 1.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}

void keyboard (unsigned char key, int x, int y)
{
	switch (key)
	{
	case 27:
		exit (0);
		break;
	default:
		break;
	}
}

int main (int argc, char** argv)
{
	glutInit (&argc, argv);
	glutInitDisplayMode (GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE);
	glutInitWindowSize (500, 500);
	glutInitWindowPosition (0, 0);
	glutCreateWindow ("Serpenski Polyhedra");
	init();

	glutDisplayFunc (display);
	glutIdleFunc(idle);
	glutReshapeFunc (reshape);
	glutKeyboardFunc (keyboard);
	glutMainLoop();

	return 0;
}
